package com.pms.api;

import com.baomidou.mybatisplus.plugins.Page;
import com.pms.controller.BaseController;
import com.pms.entity.UserInfo;
import com.pms.exception.R;
import com.pms.partitionPoints.service.ElectronicMapService;
import com.pms.partitionPoints.service.IKyGroupOrganizationService;
import com.pms.rpc.UserService;
import com.pms.validator.Assert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by 宏铭科技
 * 电子地图
 *
 * @auther ASUS_
 * @Date 2018/8/16.
 */
@RestController
@RequestMapping(value = "/apiElectronicMap")
@Api(value = "管网电子地图Api接口", description = "管网电子地图Api接口")
public class ApiElectronicMapController extends BaseController {
    @Autowired
    private IKyGroupOrganizationService groupOrganizationService;
    @Autowired
    UserService userService;

    @Autowired
    private ElectronicMapService electronicMapService;

    @ApiOperation(value = "查询电子地图分区信息")
    @RequestMapping(value = "/readDmaMapInfo", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "level", value = "查询级别(2/3/4 - 一/二/三级分区,5-测点)", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "id", value = "分区/测点id,查询对应的分区/测点 信息", required = false, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "parentId", value = "上级id,查询下级分区/测点 信息", required = false, dataType = "String", paramType = "form")
    })
    public R readDmaMapInfo(Integer level, Integer id, Integer parentId) {
        Assert.parameterIsNull(level, "参数level不能为空");
        // 获取当前用户角色
        Map<String, String> currentUserMap = getCurrentUserMap();
        UserInfo currentUserInfo = userService.getUserByUsername(currentUserMap.get("userName"), currentUserMap.get("companyCode"));
        if (null == currentUserInfo || null == currentUserInfo.getId()) {
            return R.error(400, "请重新登录");
        }
        Map<String, Object> userPermiss = userService.getApiPermission(Long.parseLong(currentUserInfo.getId()), 1, "电子地图", 1, null);
        if (null == userPermiss) {
            return R.error(400, "您没有进入该页面的权限");
        }
        if (level < 2 || level > 5) {
            return R.error(400, "参数level值异常");
        }
        String companyCode = getCurrentCompanyCode();
        Assert.parameterIsBlank(companyCode, "请求头参数异常");
        Long roleId = null;
        Integer roleType = null;
        try {
            roleId = getCurrentRoleId();
            roleType = getCurrentRoleType();
        } catch (NumberFormatException ex) {
            return R.error(400, "请求头参数异常");
        }
        String roleOrgIds = null;
        if (1 != roleType) {// 自定义角色
            roleOrgIds = groupOrganizationService.getOrgIdsStrByGroupId(roleId + "");
            Assert.parameterIsBlank(roleOrgIds, "您暂无机构权限，请联系管理员");
        }
        Map<String, Object> resultDataMap = new HashMap<String, Object>();
        Map<String, Object> orgDmaParamMap = new HashMap<String, Object>();
        orgDmaParamMap.put("companyCode", companyCode);
        orgDmaParamMap.put("roleOrgIds", roleOrgIds);
        orgDmaParamMap.put("level", level);
        orgDmaParamMap.put("parentId", parentId);
        orgDmaParamMap.put("id", id);
        if (level == 2 || level == 3 || level == 4) { // 查询分区
            /**
             * 查询分区统计信息
             */
            //先查询分区信息 ()
            List<Map<String, Object>> orgDmaList = electronicMapService.getOrgDmaInfoByLevel(orgDmaParamMap);
            StringBuilder orgDmaIdsStr = null;//获取分区id字符串
            for (int x = 0, length = orgDmaList.size(); x < length; x++) {
                if (orgDmaIdsStr == null) {
                    orgDmaIdsStr = new StringBuilder().append(orgDmaList.get(x).get("id"));
                }
                orgDmaIdsStr.append(",").append(orgDmaList.get(x).get("id"));
            }
            if (orgDmaIdsStr == null) {
                if (resultDataMap.get("measurepointInfoList") == null) {
                    resultDataMap.put("measurepointInfoList", new ArrayList<>());
                }
                if (resultDataMap.get("dmaInfoList") == null) {
                    resultDataMap.put("dmaInfoList", new ArrayList<>());
                }
//                return R.ok().put("data", resultDataMap);
            }
            Map<Integer, Long> measurepointDirectionMap = new HashMap<Integer, Long>(); //计量测点流向Map
            Map<Integer, String> measurepointGroupIdMap = new HashMap<Integer, String>(); //计量测点数据查询表Map
            Map<Integer, Integer> dmaMeasurepointLineNumMap = new HashMap<Integer, Integer>(); //分区测点在线数量 Map
            Map<Integer, Integer> dmaMeasurepointTotalNumMap = new HashMap<Integer, Integer>(); //分区测点总数量 Map
            Map<Integer, Integer> measurepointDmaMap = new HashMap<Integer, Integer>(); //计量测点所属分区Map
            if (orgDmaIdsStr != null) {


                //查询 所有分区 中的测点信息
                List<Map<String, Object>> orgDmaMeasurepointInfoList = electronicMapService.getDmaMeasurepointInfo(orgDmaIdsStr.toString());

                for (int x = 0, lenth = orgDmaMeasurepointInfoList.size(); x < lenth; x++) {
                    if (orgDmaMeasurepointInfoList.get(x) == null) {
                        orgDmaMeasurepointInfoList.remove(x);
                        --x;
                        --lenth;
                        continue;
                    }
                    Integer orgDmaId = (Integer) orgDmaMeasurepointInfoList.get(x).get("orgDmaId");
                    //记录 分区从测点数量
                    dmaMeasurepointTotalNumMap.put(orgDmaId, (dmaMeasurepointTotalNumMap.get(orgDmaId) == null ? 0 : dmaMeasurepointTotalNumMap.get(orgDmaId)) + 1);
                    if ((Integer) orgDmaMeasurepointInfoList.get(x).get("measurepointStatus") == 1) {// 记录分区 在线测点数量
                        dmaMeasurepointLineNumMap.put(orgDmaId, (dmaMeasurepointLineNumMap.get(orgDmaId) == null ? 0 : dmaMeasurepointLineNumMap.get(orgDmaId)) + 1);
                    }

                    Integer measurepointId = (Integer) orgDmaMeasurepointInfoList.get(x).get("measurepointId");
                    if ((Long) orgDmaMeasurepointInfoList.get(x).get("measurepointDirection") < 5) {// 测点 有流向,为计量测点
                        Integer organizationGroupId = (Integer) orgDmaMeasurepointInfoList.get(x).get("organizationGroupId");
                        // 保存计量测点流向
                        measurepointDirectionMap.put(measurepointId, (Long) orgDmaMeasurepointInfoList.get(x).get("measurepointDirection"));
                        // 保存 计量测点 分区
                        measurepointDmaMap.put(measurepointId, orgDmaId);
                        // 保存计量测点 查询表Map
                        measurepointGroupIdMap.put(organizationGroupId, (measurepointGroupIdMap.get(organizationGroupId) == null ? "" : measurepointGroupIdMap.get(organizationGroupId) + ",") + measurepointId);
                    }
                }
                // 生成 测点上报数据查询 参数
                List<Map<String, Object>> measurepointDataParamMap = getMeasurepointDataParamMapList(measurepointGroupIdMap);
                Map<Integer, BigDecimal> dmaExportInstantaneousMap = new HashMap<Integer, BigDecimal>();//分区出水瞬时流量统计Map
                Map<Integer, BigDecimal> dmaEntryInstantaneousMap = new HashMap<Integer, BigDecimal>();//分区进水瞬时流量统计Map
                if (!measurepointDataParamMap.isEmpty()) {
                    List<Map<String, Object>> measurepointInstantaneousFlowList = electronicMapService.getMeasurepointInstantaneousFlow(measurepointDataParamMap);
                    for (int x = 0, len = measurepointInstantaneousFlowList.size(); x < len; x++) {
                        if (measurepointInstantaneousFlowList.get(x) == null) {
                            measurepointInstantaneousFlowList.remove(x);
                            --x;
                            --len;
                            continue;
                        }
                        BigDecimal instantaneousFlowVar = (BigDecimal) measurepointInstantaneousFlowList.get(x).get("instantaneousFlow");
                        Integer measurepointId = (Integer) measurepointInstantaneousFlowList.get(x).get("equipmentId");
                        if (instantaneousFlowVar == null) {
                            instantaneousFlowVar = new BigDecimal(0.0);
                        }
                        Integer measurepointDmaId = measurepointDmaMap.get(measurepointId);// 获取测点对应的 分区id
                        //计算 分区 耗水统计
                        if (measurepointDirectionMap.get(measurepointId) == 0L) {// 测点方向为 0-流出,1-流入
                            dmaExportInstantaneousMap.put(measurepointDmaId, (dmaExportInstantaneousMap.get(measurepointDmaId) == null ? new BigDecimal(0.0) : dmaExportInstantaneousMap.get(measurepointDmaId)).add(instantaneousFlowVar));
                        } else {
                            dmaEntryInstantaneousMap.put(measurepointDmaId, (dmaEntryInstantaneousMap.get(measurepointDmaId) == null ? new BigDecimal(0.0) : dmaEntryInstantaneousMap.get(measurepointDmaId)).add(instantaneousFlowVar));
                        }
                    }
                }
                // 添加 测点数量统计  及  瞬时耗水统计 返回
                for (int x = 0, length = orgDmaList.size(); x < length; x++) {
                    Integer orgDmaId = (Integer) orgDmaList.get(x).get("id");
                    Integer onlineMeasurepointNum = dmaMeasurepointLineNumMap.get(orgDmaId) == null ? 0 : dmaMeasurepointLineNumMap.get(orgDmaId);
                    Integer totalMeasurepointNum = dmaMeasurepointTotalNumMap.get(orgDmaId) == null ? 0 : dmaMeasurepointTotalNumMap.get(orgDmaId);
                    orgDmaList.get(x).put("onlineMeasurepointNum", onlineMeasurepointNum);// 在线测点数量
                    orgDmaList.get(x).put("totalMeasurepointNum", totalMeasurepointNum);// 总测点数量
                    orgDmaList.get(x).put("nolineMeasurepointNum", totalMeasurepointNum - onlineMeasurepointNum);// 离线测点数量
                    BigDecimal exportCountInstantaneousFlow = dmaExportInstantaneousMap.get(orgDmaId) == null ? new BigDecimal(0.0) : dmaExportInstantaneousMap.get(orgDmaId);
                    BigDecimal entryCountInstantaneousFlow = dmaEntryInstantaneousMap.get(orgDmaId) == null ? new BigDecimal(0.0) : dmaEntryInstantaneousMap.get(orgDmaId);
                    orgDmaList.get(x).put("exportCountInstantaneousFlow", exportCountInstantaneousFlow);// 出水口总瞬时流量
                    orgDmaList.get(x).put("entryCountInstantaneousFlow", entryCountInstantaneousFlow);// 进水口总瞬时流量
                    orgDmaList.get(x).put("countInstantaneousFlow", entryCountInstantaneousFlow.subtract(exportCountInstantaneousFlow));// 瞬时耗水流量
                    if (orgDmaList.get(x).get("monitoringsites") == null) {
                        orgDmaList.get(x).put("monitoringsites", "");
                    }
                }
                resultDataMap.put("dmaInfoList", orgDmaList);
                measurepointDirectionMap = null; //计量测点流向Map
                measurepointGroupIdMap = null; //计量测点数据查询表Map
                dmaMeasurepointLineNumMap = null; //分区测点在线数量 Map
                dmaMeasurepointTotalNumMap = null; //分区测点总数量 Map
                measurepointDmaMap = null; //计量测点所属分区Map
                dmaExportInstantaneousMap = null;//分区出水瞬时流量统计Map
                dmaEntryInstantaneousMap = null;//分区进水瞬时流量统计Map
            }
            /**
             * 查询分区同级的  散落测点
             */
//            if(level==3||level==4){//一级分区，无需查询散落点
            if (id == null) {
                if (level == 3) {
                    if (parentId != null) {
                        orgDmaParamMap.put("oneLevelOrgId", parentId);
                    }
                }
                if (level == 4) {
                    if (parentId != null) {
//                            orgDmaParamMap.put("oneLevelOrgId",electronicMapService.getOneLevelOrgId(parentId));
                        orgDmaParamMap.put("oneLevelOrgId", parentId);
                    }
                }
                measurepointGroupIdMap = new HashMap<Integer, String>();
                List<Map<String, Object>> dmaDorderEquipmentList = null;
                if (level > 2) {
                    dmaDorderEquipmentList = electronicMapService.getDmaDorderEquipment(orgDmaParamMap);
                }
                if (level == 2) {
                    if (1 == roleType) {
                        dmaDorderEquipmentList = electronicMapService.getDmaDorderEquipment(orgDmaParamMap);
                    }
                    if (1 != roleType) {
                        dmaDorderEquipmentList = new ArrayList<Map<String, Object>>();
                    }
                }
//                    List<Map<String,Object>> dmaDorderEquipmentList = electronicMapService.getDmaDorderEquipment(orgDmaParamMap);
                for (int x = 0, len = dmaDorderEquipmentList.size(); x < len; x++) {
                    if (dmaDorderEquipmentList.get(x) == null) {
                        dmaDorderEquipmentList.remove(x);
                        --x;
                        --len;
                        continue;
                    }
                    if (dmaDorderEquipmentList.get(x).get("id") == null) {
                        dmaDorderEquipmentList.remove(x);
                        --x;
                        --len;
                        continue;
                    }
                    Integer organizationGroupId = (Integer) dmaDorderEquipmentList.get(x).get("organizationGroupId");
                    Integer measurepointId = (Integer) dmaDorderEquipmentList.get(x).get("id");
                    // 保存计量测点 查询表Map
                    measurepointGroupIdMap.put(organizationGroupId, (measurepointGroupIdMap.get(organizationGroupId) == null ? "" : measurepointGroupIdMap.get(organizationGroupId) + ",") + measurepointId);
                }
                // 生成 测点上报数据查询 参数
                List<Map<String, Object>> measurepointDataParamMap = getMeasurepointDataParamMapList(measurepointGroupIdMap);
                if (!measurepointDataParamMap.isEmpty()) {
                    List<Map<String, Object>> measurepointDataInfoList = electronicMapService.getMeasurepointDataInfo(measurepointDataParamMap);
                    Map<Integer, Map<String, Object>> measurepointDataInfoMap = new HashMap<Integer, Map<String, Object>>();
                    for (int x = 0, len = measurepointDataInfoList.size(); x < len; x++) {
                        measurepointDataInfoMap.put((Integer) measurepointDataInfoList.get(x).get("equipmentId"), measurepointDataInfoList.get(x));
                    }
                    for (int x = 0, len = dmaDorderEquipmentList.size(); x < len; x++) {
                        if (dmaDorderEquipmentList.get(x) == null) {
                            dmaDorderEquipmentList.remove(x);
                            --x;
                            --len;
                            continue;
                        }
                        Map<String, Object> measurepointDataInfo = measurepointDataInfoMap.get(dmaDorderEquipmentList.get(x).get("id"));
                        dmaDorderEquipmentList.get(x).putAll(measurepointDataInfo == null ? new HashMap<String, Object>() : measurepointDataInfo);
                    }
                }
                resultDataMap.put("measurepointInfoList", dmaDorderEquipmentList);
            }
//            }

        }
        if (level == 5) {// 查询测点
            List<Map<String, Object>> measurepointInfoList = electronicMapService.getMeasurepointList(orgDmaParamMap);
            //查询测点上报最新数据
            measurepointInfoList = completionMeasurepointData(measurepointInfoList);
            resultDataMap.put("measurepointInfoList", measurepointInfoList);
            resultDataMap.put("dmaInfoList", new ArrayList<>());
        }
        if (resultDataMap.get("measurepointInfoList") == null) {
            resultDataMap.put("measurepointInfoList", new ArrayList<>());
        }
        if (resultDataMap.get("dmaInfoList") == null) {
            resultDataMap.put("dmaInfoList", new ArrayList<>());
        }
        return R.ok().put("data", resultDataMap);
    }


    @ApiOperation(value = "查询电子地图测点-实时监控")
    @RequestMapping(value = "/readMapRealTimeMonitor", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "measurepointId", value = "测点id", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "ordDmaId", value = "分区id", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "分页查询条数,默认10条", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "分页查询页数,默认第1页", required = false, dataType = "int", paramType = "form")
    })
    public R readMapRealTimeMonitor(Integer pageNum, Integer pageSize, Integer measurepointId, Integer ordDmaId) {
        String companyCode = getCurrentCompanyCode();
        Assert.parameterIsBlank(companyCode, "请求头参数异常");
        Long roleId = null;
        Integer roleType = null;
        try {
            roleId = getCurrentRoleId();
            roleType = getCurrentRoleType();
        } catch (NumberFormatException ex) {
            return R.error(400, "请求头参数异常");
        }
        String roleOrgIds = null;
        if (1 != roleType) {// 自定义角色
            roleOrgIds = groupOrganizationService.getOrgIdsStrByGroupId(roleId + "");
            Assert.parameterIsBlank(roleOrgIds, "您暂无机构权限，请联系管理员");
        }
        if (pageNum == null || pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = 10;
        }
        if (ordDmaId != null && ordDmaId == -1) {
            ordDmaId = null;
        }
        if (measurepointId != null && measurepointId == -1) {
            measurepointId = null;
        }
        Page<Map<String, Object>> pages = new Page<Map<String, Object>>(pageNum, pageSize);
        Map<String, Object> orgDmaParamMap = new HashMap<String, Object>();
        orgDmaParamMap.put("companyCode", companyCode);
        orgDmaParamMap.put("roleOrgIds", roleOrgIds);
        orgDmaParamMap.put("parentId", ordDmaId);
        orgDmaParamMap.put("id", measurepointId);
        Integer measurepointNum = electronicMapService.getCountMeasurepointNum(orgDmaParamMap);
        pages.setTotal(measurepointNum == null ? 0 : measurepointNum);
        orgDmaParamMap.put("startRow", (pageNum - 1) * pageSize);
        orgDmaParamMap.put("pageSize", pageSize);
        List<Map<String, Object>> measurepointInfoList = electronicMapService.getMeasurepointList(orgDmaParamMap);
        //查询测点上报最新数据
        measurepointInfoList = completionMeasurepointData(measurepointInfoList);
        pages.setRecords(measurepointInfoList);
        return R.ok().put("data", pages);
    }

    @ApiOperation(value = "查询分区/测点详情")
    @RequestMapping(value = "/readOrgDmaMeasurepointInfo", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "level", value = "级别level", required = false, dataType = "int", paramType = "form"),
    })
    public R readOrgDmaMeasurepointInfo(Integer id, Integer level) {
        String companyCode = getCurrentCompanyCode();
        Assert.parameterIsBlank(companyCode, "请求头参数异常");
        Assert.isNull(id, "请选择分区");
        Assert.isNull(level, "请选择分区");
        List<Map<String, Object>> measurepointInfoList = null;
        Map<String, Object> orgDmaParamMap = new HashMap<String, Object>();
        orgDmaParamMap.put("companyCode", companyCode);
        if (level != 5) {// 查询分区
            if (id != null && id == -1) {
                id = null;
            }
            orgDmaParamMap.put("parentId", id);// 分区id
        }
        if (level == 5) {// 查询测点
            orgDmaParamMap.put("id", id);
        }
        measurepointInfoList = electronicMapService.getMeasurepointList(orgDmaParamMap);
        //查询测点上报最新数据
        if (measurepointInfoList != null) {
            measurepointInfoList = completionMeasurepointData(measurepointInfoList);
        }
        return R.ok().put("data", measurepointInfoList == null ? new ArrayList<>() : measurepointInfoList).put("level", level);
    }


    /**
     * 查询-补全测点上报数据
     *
     * @param measurepointInfoList111 测点集合
     * @return
     */
    public List<Map<String, Object>> completionMeasurepointData(List<Map<String, Object>> measurepointInfoList111) {
        Map<Integer, String> measurepointGroupIdMap = new HashMap<Integer, String>();
        for (int x = 0, len = measurepointInfoList111.size(); x < len; x++) {
            if (measurepointInfoList111.get(x) == null) {
                measurepointInfoList111.remove(x);
                --x;
                --len;
                continue;
            }
            Integer organizationGroupId = (Integer) measurepointInfoList111.get(x).get("organizationGroupId");
            // 保存计量测点 查询表Map
            measurepointGroupIdMap.put(organizationGroupId, (measurepointGroupIdMap.get(organizationGroupId) == null ? "" : measurepointGroupIdMap.get(organizationGroupId) + ",") + measurepointInfoList111.get(x).get("id"));
        }
        // 生成 测点上报数据查询 参数
        List<Map<String, Object>> measurepointDataParamMap = getMeasurepointDataParamMapList(measurepointGroupIdMap);
        if (!measurepointDataParamMap.isEmpty()) {
            List<Map<String, Object>> measurepointDataInfoList = electronicMapService.getMeasurepointDataInfo(measurepointDataParamMap);
            Map<Integer, Map<String, Object>> measurepointDataInfoMap = new HashMap<Integer, Map<String, Object>>();
            for (int x = 0, len = measurepointDataInfoList.size(); x < len; x++) {
                measurepointDataInfoMap.put((Integer) measurepointDataInfoList.get(x).get("equipmentId"), measurepointDataInfoList.get(x));
            }
            for (int x = 0, len = measurepointInfoList111.size(); x < len; x++) {
                if (measurepointInfoList111.get(x) == null) {
                    measurepointInfoList111.remove(x);
                    --x;
                    --len;
                    continue;
                }
                Map<String, Object> measurepointDataInfo = measurepointDataInfoMap.get(measurepointInfoList111.get(x).get("id"));
                measurepointInfoList111.get(x).putAll(measurepointDataInfo == null ? new HashMap<String, Object>() : measurepointDataInfo);
            }
        }
        return measurepointInfoList111;
    }

    /**
     * 根据 测点查询表Map 获取测点查询参数
     *
     * @param measurepointGroupIdMap 测点查询表Map
     * @return List<Map<String,Object>> 测点查询参数(tableSuffix-表名后缀,measurepointIds-查询参数)
     */
    public static List<Map<String, Object>> getMeasurepointDataParamMapList(Map<Integer, String> measurepointGroupIdMap) {
        List<Map<String, Object>> measurepointDataParamMap = new ArrayList<Map<String, Object>>();
        for (Map.Entry<Integer, String> entry : measurepointGroupIdMap.entrySet()) {
            if (entry.getKey() != null) {
                Map<String, Object> paramMap = new HashMap<String, Object>();
                paramMap.put("tableSuffix", entry.getKey());
                paramMap.put("measurepointIds", entry.getValue());
                measurepointDataParamMap.add(paramMap);
            }
        }
        return measurepointDataParamMap;
    }
}
